home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1994 / MacHack 1994.toast / MacHack™ 1987-1994 / MacHack™ '90 / MacHack'90 Proceedings / A⁄Rose Techniques / Middleman.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-08  |  6.0 KB  |  225 lines  |  [TEXT/MPS ]

  1. /*
  2.  *    Middleman.c - Examples of processing/issuing requests.
  3.  *
  4.  *    Mark D. Rustad.    6/8/90.
  5.  *
  6.  *    Note that this file will not compile and run, it is just excerpts.  Not only
  7.  *    that, but it doesn't really do anything, even if it could run.  It does
  8.  *    show a few techniques that are commonly used with A/ROSE.
  9.  *
  10.  *    Also note that in this context "zip" simply means "nothing" (Any thought of
  11.  *    of "zone information protocol" should be suppressed).  This also describes
  12.  *    what this "middleman" does, nothing.  Presumably, most of the time, such
  13.  *    tasks would actually do some useful work....
  14.  */
  15.  
  16. #include <clister.h>
  17. #include <os.h>
  18. #include "FunMacros.h"
  19.  
  20. _TITLE("Middleman.c - Examples of processing/issuing requests.")
  21. _SPACE("4,20,Definitions")
  22. /*
  23.  *    Definitions.
  24.  */
  25.  
  26. /*    mCodes    */
  27.  
  28. #define    ZZDoZip        0x422    /* mCode for doing zip asynchronously */
  29. #define    ZZDontZip    0x424    /* mCode for not doing zip asynchronously */
  30. #define    ZZSyncZip    0x426    /* mCode for doing zip synchronously */
  31.  
  32. /*    Error codes */
  33.  
  34. #define    EEBadCode        0x27    /* mStatus return for bad mCode */
  35. #define    EENoResources    0x28    /* mStatus return for no resources to do request */
  36.  
  37. typedef void (*funcPtr)();
  38.  
  39. _SPACE("4,20,Globals")
  40. /*
  41.  *    Global Data.
  42.  */
  43.  
  44. tid_type    NextServerTID;    // This gets set somehow
  45. tid_type    MyTID;            // Likewise
  46.  
  47. _SPACE("4,20,Main")
  48. /*
  49.  *    Main - Here be the main loop.
  50.  */
  51.  
  52. Main()
  53. {
  54.     register AROSEmessage    *mp;
  55.  
  56.     initialize();            // There's always lots of this, right?
  57.  
  58.     for (;;)
  59.     {
  60.         mp = Receive(0, 0, 0, 0);
  61.  
  62.         /*    This checks for completions from the next server.  This approach
  63.          *    assumes that the next server does not make requests to us, but
  64.          *    only replies.  Checks could be made on mCode.
  65.          */
  66.  
  67.         if (mp->mFrom == NextServerTID)
  68.         {
  69.             ((funcPtr)mp->mSData[0])(mp);    // Call routine to complete request
  70.             continue;        // Back up to the top of the for loop
  71.         }
  72.  
  73.         switch (mp->mCode)
  74.         {
  75.         case ZZDoZip:        // Start doing zip asynchronously here
  76.             StartZipping(mp);
  77.             break;
  78.  
  79.         case ZZDontZip:        // Start not doing zip asynchronously here
  80.             StartNotZipping(mp);
  81.             break;
  82.  
  83.         case ZZSyncZip:        // Start doing zip synchronously here
  84.             StartSyncZipping(mp);
  85.             break;
  86.  
  87.         default:            // Got a bad mCode
  88.             if (mp->mCode & 0x8001)    // If a reply or undeliverable
  89.             {
  90.                 FreeMsg(mp);    // Just throw it away
  91.             }
  92.             else
  93.             {
  94.                 Reply(mp, EEBadCode);
  95.             }
  96.         }
  97.     }
  98. }
  99.  
  100. _SPACE("4,20,StartZipping")
  101. /*
  102.  *    StartZipping - Begin asynchronous zip processing.
  103.  *
  104.  *    This routine demonstrates one strategy for handling asynchronous requests.
  105.  *
  106.  *    Inputs:
  107.  *        mp     - Points to request message.
  108.  */
  109.  
  110. void    StartZipping(AROSEmessage *mp)
  111. {
  112.     register AROSEmessage    *cmp;
  113.     void    CompleteZipping(AROSEmessage *mp);
  114.  
  115.     if ((cmp = GetMsg()) == 0)
  116.     {
  117.         /*    Deal with lack of messages somehow.  Perhaps maintain an internal
  118.          *    queue of requests that had to be deferred (note that if things must
  119.          *    be done in order, you'll have to queue all incoming requests to the
  120.          *    queue (FIFO) whenever anything is on the queue).
  121.          *
  122.          *    Many times, a task like this would preallocate a few message
  123.          *    buffers during initialization and keep them in a list.  Whenever
  124.          *    the list was empty, the task would either try to do a GetMsg or
  125.          *    would simply queue the request and wait for the completions to
  126.          *    come back.  Those completion message buffers would then be reused
  127.          *    to issue new requests.
  128.          */
  129.  
  130.         Reply(mp, EENoResources);    // We cop out here...
  131.         return;
  132.     }
  133.  
  134.     cmp->mTo = NextServerTID;
  135.     cmp->mCode = NSCode;        // mCode for next server's request
  136.     cmp->mSData[0] = (long)CompleteZipping;    // Points to completion routine
  137.     cmp->mSData[1] = (long)mp;    // Save pointer to client's request being processed
  138.     cmp->mOData[0] = 100214;    // Hypothetical data for hypothetical server
  139.     Send(cmp);
  140. }
  141.  
  142. _SPACE("4,20,CompleteZipping")
  143. /*
  144.  *    CompleteZipping - Complete asynchronous zip request.
  145.  *
  146.  *    Inputs:
  147.  *        mp        - Points to completion message.
  148.  */
  149.  
  150. void    CompleteZipping(register AROSEmessage *mp);
  151. {
  152.     register AROSEmessage    *ump;    /* User's message pointer */
  153.  
  154.     ump = (AROSEmessage *)mp->mSData[1];
  155.     Reply(ump, mp->mStatus);    /* Reply to user's message */
  156.     FreeMsg(mp);                /* Free the reply to our request */
  157. }
  158.  
  159. _SPACE("4,20,StartNotZipping")
  160. /*
  161.  *    StartNotZipping - Start not doing zip asynchronously.
  162.  *
  163.  *    This routine demonstrates a forwarding method that can sometimes be used.
  164.  *
  165.  *    Inputs:
  166.  *        mp        - Points to request message.
  167.  */
  168.  
  169. void    StartNotZipping(AROSEmessage *mp)
  170. {
  171.     /*
  172.      *    Note that this technique assumes that either no reply will be sent to the
  173.      *    user, or that the user will not care that the mFrom is not where he sent
  174.      *    the original request.  It also assumes that the mCodes just "happened" to
  175.      *    be the same.  In other cases, if mOData is not used by in the request, this
  176.      *    intermediary may save mFrom in mOData, change mFrom and forward the request,
  177.      *    then catch the reply and undo the changes later.
  178.      */
  179.  
  180.     mp->mTo = NextServerTID;    // Just forward it on
  181.     mp->mOData[2] = 12;            // Maybe add a little info
  182.     Send(mp);
  183. }
  184.  
  185. _SPACE("4,20,StartSyncZipping")
  186. /*
  187.  *    StartSyncZipping - Start doing zip synchronously.
  188.  *
  189.  *    This routine demonstrates handling a synchronous request.  It uses a
  190.  *    sleazy trick to avoid the case of not having a message buffer available.
  191.  *    Since you probably went to MacHack to learn sleazy tricks, it is included
  192.  *    here to satisfy your lust for sleazy tricks.
  193.  */
  194.  
  195. void    StartSyncZipping(register AROSEmessage *mp)
  196. {
  197.     long    id;
  198.     AROSEmessage    tmp;        // NOTE - NOT a pointer!
  199.  
  200.     /*
  201.      *    The following line saves the original request message on the stack, so
  202.      *    we can use that message buffer to make the synchronous request.  Of
  203.      *    course, you could add logic to only do the copying if no messages were
  204.      *    available, but this example doesn't to keep things simple.
  205.      */
  206.  
  207.     tmp = *mp;                    // Save original request on stack!
  208.  
  209.     mp->mTo = NextServerTID;    // Set up request to next server
  210.     mp->mFrom = MyTID;
  211.     mp->mCode = NextServermCodeValue;
  212.     id = mp->mId;
  213.     Send(mp);
  214.  
  215.     mp = Receive(id, 0, 0, 0);    // Wait for completion
  216.  
  217.     id = mp->mStatus;            // Save status
  218.  
  219.     *mp = tmp;                    // Restore original request!
  220.  
  221.     Reply(mp, id);                // Send reply to original request
  222. }
  223.  
  224. /*    End of Middleman.c    */
  225.